package cn.exrick.xboot.base.login

import cn.exrick.xboot.base.entity.DepartmentUser
import cn.exrick.xboot.base.entity.EnterpriseEmployee
import cn.exrick.xboot.base.entity.SecurityAdvisor
import cn.exrick.xboot.base.entity.SupervisionUser
import cn.exrick.xboot.base.service.IDepartmentUserService
import cn.exrick.xboot.base.service.IEnterpriseEmployeeService
import cn.exrick.xboot.base.service.ISecurityAdvisorService
import cn.exrick.xboot.base.service.ISupervisionUserService
import cn.exrick.xboot.core.common.constant.CommonConstant
import cn.exrick.xboot.core.common.utils.CommonUtil
import cn.exrick.xboot.core.common.utils.RedisUtil
import cn.exrick.xboot.core.common.utils.ResultUtil
import cn.exrick.xboot.core.common.utils.SecurityUtil
import cn.exrick.xboot.core.common.vo.Result
import cn.exrick.xboot.core.entity.User
import cn.exrick.xboot.core.entity.UserRole
import cn.exrick.xboot.core.service.RoleService
import cn.exrick.xboot.core.service.UserRoleService
import cn.exrick.xboot.core.service.UserService
import cn.exrick.xboot.core.service.mybatis.IUserRoleService
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.google.common.collect.Maps
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import lombok.extern.slf4j.Slf4j
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.redis.core.StringRedisTemplate
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.stereotype.Service
import java.util.logging.Logger

@Service
@Slf4j
class LoginServiceImpl : LoginService {


    val log = LoggerFactory.getLogger(LoginService::class.java)!!

    @Autowired
    private lateinit var iEnterpriseEmployeeService: IEnterpriseEmployeeService

    @Autowired
    private lateinit var iSecurityAdvisorService: ISecurityAdvisorService

    @Autowired
    private lateinit var iSupervisionUserService: ISupervisionUserService

    @Autowired
    private lateinit var userService: UserService

    @Autowired
    private lateinit var securityUtil: SecurityUtil

    @Autowired
    private lateinit var iUserRoleService: IUserRoleService

    @Autowired
    private lateinit var roleService: RoleService

    @Autowired
    private lateinit var stringRedisTemplate: StringRedisTemplate

    @Autowired
    private lateinit var iDepartmentUserService: IDepartmentUserService


    override fun appLogin(loginDto: LoginDto): Result<Any?>? {

       return loginDto.run {


           val data: MutableMap<String, Any?> = Maps.newHashMap()

            //1.判断有没有此用户
             userService.findByMobile(mobile)?.let {user ->

                when (type) {
                    0 -> {
                        //2.判断监管部门有没有此用户
                        return iSupervisionUserService.getOne(KtQueryWrapper(SupervisionUser::class.java)
                                .eq(SupervisionUser::userId, user.id))?.let {

                            //3.判断密码
                            return if (BCryptPasswordEncoder().matches(password, user.password)){

                                data["token"] = securityUtil.getToken(user.username, true)
                                data["type"] = 0

                                ResultUtil.data(data, "登录成功")

                            } else{

                                ResultUtil.error(201, "密码不一致！")
                            }

                        } ?: ResultUtil.error(202, "监管部门不存在账号！")
                    }
                    1 -> {

                        //2.判断安全顾问有没有此用户
                        return iSecurityAdvisorService.getOne(KtQueryWrapper(SecurityAdvisor::class.java)
                                .eq(SecurityAdvisor::userId, user.id))?.let {

                            //3.判断密码
                            return if (BCryptPasswordEncoder().matches(password, user.password)) {

                                data["token"] = securityUtil.getToken(user.username, true)
                                data["type"] = 1

                                ResultUtil.data(data, "登录成功")
                            } else {

                                ResultUtil.error(201, "密码不一致！")
                            }

                        } ?: ResultUtil.error(202, "安全顾问不存在账号！")

                    }

                    2 -> {

                        //2.判断员工有没有此用户
                        return iEnterpriseEmployeeService.getOne(KtQueryWrapper(EnterpriseEmployee::class.java)
                                .eq(EnterpriseEmployee::userId, user.id)
                                .last("limit 1"))?.let {

                            //3.判断密码
                            return if (BCryptPasswordEncoder().matches(password, user.password)) {

                                data["token"] = securityUtil.getToken(user.username, true)
                                data["type"] = 2

                                ResultUtil.data(data, "登录成功")

                            } else {

                                ResultUtil.error(201, "密码不一致！")
                            }

                        } ?: ResultUtil.error(202, "企业员工不存在账号！")
                    }

                    3 -> {
                        //2.判断政府部门有没有此用户
                        return iSupervisionUserService.getOne(KtQueryWrapper(SupervisionUser::class.java)
                                .eq(SupervisionUser::userId, user.id))?.let {

                            //3.判断密码
                            return if (BCryptPasswordEncoder().matches(password, user.password)){

                                data["token"] = securityUtil.getToken(user.username, true)
                                data["type"] = 3

                                ResultUtil.data(data, "登录成功")

                            } else{

                                ResultUtil.error(201, "密码不一致！")
                            }

                        } ?: ResultUtil.error(202, "政府部门不存在账号！")
                    }

                    //社会人员
                    else -> {

                        //2.判断当前登录账户有没有社会人员账号
                        return if (iUserRoleService.findByUserId(user.id).map { it.id }.contains(roleService.getRoleIdByRoleName(CommonConstant.ROLE_SOCIAL_USER))) {

                            //3.判断密码
                            return if (BCryptPasswordEncoder().matches(password, user.password)){

                                data["token"] = securityUtil.getToken(user.username, true)
                                data["type"] = 4

                                ResultUtil.data(data, "登录成功")

                            } else{

                                ResultUtil.error(201, "密码不一致！")
                            }

                        } else {

                            ResultUtil.error(202, "不存在社会人员账户")
                        }
                    }
                }

            } ?: ResultUtil.error(203, "当前手机号不存在！")

        }

    }

    override fun appRegister(loginDto: LoginDto): Result<Any?>? {

        return loginDto.run {

/*            code?.run {

                return stringRedisTemplate.opsForValue().get(CommonConstant.PRE_SMS.plus(mobile))?.let {

                    if (code == it) {

                        val userInsert = userService.save(User().apply {

                            username = loginDto.mobile
                            nickname = "安全会员用户"
                            password = BCryptPasswordEncoder().encode(loginDto.password)
                            mobile = loginDto.mobile
                        })

                        iUserRoleService.save(UserRole().apply {

                            userId = userInsert.id
                            roleId = roleService.getRoleIdByRoleName(CommonConstant.ROLE_SOCIAL_USER)
                        })

                        return ResultUtil.success("注册成功")
                    } else {

                        return ResultUtil.error(203, "验证码不一致")
                    }

                } ?: ResultUtil.error(202, "验证码失效")


            } ?: ResultUtil.error(201, "请输入验证码")*/

            val userInsert = userService.save(User().apply {

                username = loginDto.mobile
                nickname = "安全会员用户"
                password = BCryptPasswordEncoder().encode(loginDto.password)
                mobile = loginDto.mobile
            })

            iUserRoleService.save(UserRole().apply {

                userId = userInsert.id
                roleId = roleService.getRoleIdByRoleName(CommonConstant.ROLE_SOCIAL_USER)
            })

            return ResultUtil.success("注册成功")
        }
    }

    override fun appForgetPassword(loginDto: LoginDto): Result<Any?>? {

        return loginDto.run {

           /* code?.run {

                return stringRedisTemplate.opsForValue().get(CommonConstant.PRE_SMS.plus(mobile))?.let {

                    if (code == it) {

                        return userService.findByMobile(mobile)?.let {

                            it.password = BCryptPasswordEncoder().encode(loginDto.password)
                            userService.update(it)

                            return ResultUtil.success("修改密码成功")
                        } ?: ResultUtil.error(204, "不存在当前用户")

                    } else {

                        return ResultUtil.error(203, "验证码不一致")
                    }

                } ?: ResultUtil.error(202, "验证码失效")


            } ?: ResultUtil.error(201, "请输入验证码")*/
            return userService.findByMobile(mobile)?.let {

                it.password = BCryptPasswordEncoder().encode(loginDto.password)
                userService.update(it)

                return ResultUtil.success("修改密码成功")
            } ?: ResultUtil.error(204, "不存在当前用户")
        }


    }

    override fun removeUser(userIds: String): Result<Any>? {

        return try {

            userIds.split(",").forEach { userId ->

                userService.get(userId)?.run {

                    runBlocking {

                        //1. 判断是否是监管部门
                        launch {

                            iSupervisionUserService.getOne(KtQueryWrapper(SupervisionUser::class.java)
                                    .eq(SupervisionUser::userId, id))?.let {

                                iSupervisionUserService.removeById(it.id)
                            }
                        }

                        //2. 判断政府部门
                        launch {

                            iDepartmentUserService.getOne(KtQueryWrapper(DepartmentUser::class.java)
                                    .eq(DepartmentUser::userId, id))?.let {

                                iDepartmentUserService.removeById(it.id)
                            }
                        }

                        //3. 判断安全顾问
                        launch {

                            iSecurityAdvisorService.getOne(KtQueryWrapper(SecurityAdvisor::class.java)
                                    .eq(SecurityAdvisor::userId, id))?.let {

                                iSecurityAdvisorService.removeById(it.id)
                            }
                        }

                        //4. 判断企业人员
                        launch {

                            iSupervisionUserService.getOne(KtQueryWrapper(SupervisionUser::class.java)
                                    .eq(SupervisionUser::userId, id))?.let {

                                iSupervisionUserService.removeById(it.id)
                            }
                        }

                        //5. 判断员工
                        launch {

                            iEnterpriseEmployeeService.getOne(KtQueryWrapper(EnterpriseEmployee::class.java)
                                    .eq(EnterpriseEmployee::userId, id))?.let {

                                iEnterpriseEmployeeService.removeById(it.id)
                            }
                        }

                        //6. 删除角色
                        launch {

                            iUserRoleService.removeUserRolesByUserId(id)
                        }
                    }

                    userService.delete(id)
                }
            }
            ResultUtil.success("移除成功")
        }catch (e : Exception) {
            ResultUtil.error(e.message);
        }

    }
}
